package com.hzncc.flowable_diboot.service.impl;

import com.diboot.core.binding.Binder;
import com.diboot.core.binding.QueryBuilder;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
import com.diboot.core.util.SqlExecutor;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Pagination;
import com.diboot.iam.util.IamSecurityUtils;
import com.diboot.notification.config.Cons;
import com.diboot.notification.entity.Message;
import com.hzncc.flowable_diboot.dto.ToDoListDTO;
import com.hzncc.flowable_diboot.entity.ToDoList;
import com.hzncc.flowable_diboot.mapper.ToDoListMapper;
import com.hzncc.flowable_diboot.rabbitmq.service.impl.SendMessageService;
import com.hzncc.flowable_diboot.service.ToDoListService;
import com.hzncc.flowable_diboot.util.ConstantUtil;
import com.hzncc.flowable_diboot.vo.ToDoListListVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.List;


/**
 * 待办 相关Service实现类
 *
 * @author MyName
 * @version 1.0
 * @date 2024-06-17
 * Copyright © MyCorp
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ToDoListServiceImpl extends BaseServiceImpl<ToDoListMapper, ToDoList> implements ToDoListService {

    private final SendMessageService sendMessageService;

    @Override
    public void createToDo(ToDoList todoList) {
        LocalDateTime startTime = todoList.getStartTime();
        if (startTime != null) {
            // 提前30分钟提醒
            todoList.setReminderTime(startTime.minusMinutes(ConstantUtil.BEFORE_HALF_HOUR));
            LocalDateTime reminderTime = todoList.getReminderTime();
            if (reminderTime.isBefore(LocalDateTime.now())){
                //throw new RuntimeException("时间太近，请重新选择");
                todoList.setHasMsg(true); // 不生成消息
            }
            // 当天
            else if (reminderTime.toLocalDate().equals(LocalDate.now())) {
                sendMessage(todoList);
            }
        }
        createEntity(todoList);
    }

    @Override
    public void createToDo(List<ToDoList> todoLists) {
        for (ToDoList todoList : todoLists) {
            todoList.setTenantId(IamSecurityUtils.getCurrentTenantId());
            LocalDateTime startTime = todoList.getStartTime();
            if (startTime != null) {
                // 提前30分钟提醒
                todoList.setReminderTime(startTime.minusMinutes(ConstantUtil.BEFORE_HALF_HOUR));
                LocalDateTime reminderTime = todoList.getReminderTime();
                // 当天
                if (reminderTime.toLocalDate().equals(LocalDate.now())) {
                    sendMessage(todoList);
                }
            }
        }
        createEntities(todoLists);
    }

    @Override
    public JsonResult<List<ToDoListListVO>> searchToDoList(ToDoListDTO queryDto, Pagination pagination) {
        queryDto.setExecutor(IamSecurityUtils.getCurrentUserId());
        if (S.isEmpty(pagination.getOrderBy())){
            pagination.setOrderBy(Pagination.ORDER_BY_CREATE_TIME_DESC);
        }
        List<ToDoListListVO> voList = getViewObjectList(QueryBuilder.toQueryWrapper(queryDto), pagination, ToDoListListVO.class);
        // 手动绑定数据
        Binder.bindRelations(voList);
        return JsonResult.OK(voList).bindPagination(pagination);
    }

    /**
     * 生成通知 (延时消息)
     *
     * @author 陈广煜
     * @date 2024/6/19
     */
    public void generateNotification() {
        // 获取当前小时内需要发送通知待办
        String sql = "select id, tenant_id, type, start_time, reminder_time, mission, model, dis_person, executor, dis_time, has_msg " +
                "from mdl_to_do_list where is_deleted =0 and HOUR(reminder_time) = HOUR(now()) and DATE(reminder_time) = curdate() and has_msg = 0";
        JdbcTemplate jdbcTemplate = SqlExecutor.getJdbcTemplate();
        List<ToDoList> list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(ToDoList.class));
        // 发送延迟消息
        sendMessage(list);
        List<String> ids = BeanUtils.collectToList(list, ToDoList::getId);
        // 更新待办状态
        String up = "update mdl_to_do_list set has_msg = 1 where id in ('" + S.join(ids, "','") + "')";
        jdbcTemplate.update(up);
    }

    /**
     * 发送延迟消息
     *
     * @param todoLists
     * @author 陈广煜
     * @date 2024/6/19
     */
    private void sendMessage(List<ToDoList> todoLists) {
        for (ToDoList todoList : todoLists) {
            todoList.setHasMsg(true);
            Message record = new Message();
            record.setContent(todoList.getMission());
            record.setAppModule(todoList.getModel());
            record.setTitle("待办事项");
            record.setReceiver(todoList.getExecutor());
            record.setChannel(Cons.MESSAGE_CHANNEL.SYS_MSG.name());
            record.setStatus(Cons.MESSAGE_STATUS.PENDING.name());
            record.setTemplateId("");
            record.setBusinessCode("todo");
            record.setBusinessType("todo");
            record.setSender("0");
            record.setTenantId(todoList.getTenantId());
            LocalDateTime reminderTime = todoList.getReminderTime();
            long end = reminderTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            long now = System.currentTimeMillis();
            long res = end - now;
            sendMessageService.sendDelayMessage(record, (int) res);
        }
    }

    private void sendMessage(ToDoList todoList) {
        sendMessage(Collections.singletonList(todoList));
    }
}